package com.m3958.logcollector.util.common;

import java.util.Optional;
import java.util.stream.Stream;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

import com.m3958.logcollector.authenticationtoken.M3958LoginAuthenticationToken;
import com.m3958.logcollector.domain.Person;
import com.m3958.logcollector.vo.PersonVo;


/**
 * 
 * @author jianglibo@gmail.com
 *
 */
public class M3958SecurityUtil {

    public static void loginAs(Authentication au) {
        au.setAuthenticated(true);
        SecurityContextHolder.getContext().setAuthentication(au);
    }


    public static Optional<PersonVo> getLoginPersonVo() {
        Authentication au = SecurityContextHolder.getContext().getAuthentication();
        if (au == null) {
            return Optional.empty();
        } else {
            return Optional.of((PersonVo) au.getPrincipal());
        }
    }
    
    public static long getLoginPersonId() {
        if (getLoginPersonVo().isPresent()) {
            return getLoginPersonVo().get().getId();
        } else {
            return Long.MIN_VALUE;
        }
    }

    public static Authentication getLoginAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }

    public static void doLogin(Person person) {
        doLogin(SecurityContextHolder.getContext(), person);
    }
    
    public static void doLogin(M3958LoginAuthenticationToken mat) {
        mat.setAuthenticated(true);
        SecurityContextHolder.getContext().setAuthentication(mat);
    }


    public static boolean hasRole(String rn) {
        if (getLoginAuthentication() == null) {
            return false;
        }
        if (getLoginAuthentication().isAuthenticated()) {
            return getLoginAuthentication().getAuthorities().stream().anyMatch(ga -> rn.equals(ga.getAuthority()));
        }
        return false;
    }
    
    public static void logout() {
        SecurityContextHolder.clearContext();
    }
    
    
    public static boolean hasAnyRole(String...rns) {
        return Stream.of(rns).anyMatch(M3958SecurityUtil::hasRole);
    }

    public static SecurityContext doLogin(SecurityContext context, Person person) {
        M3958LoginAuthenticationToken uat = new M3958LoginAuthenticationToken(new PersonVo(person));
        uat.setAuthenticated(true);
        context.setAuthentication(uat);
        return context;
    }
}
